fix: prevent 500 on contributor identity update by filtering non-updatable fields#4077
fix: prevent 500 on contributor identity update by filtering non-updatable fields#4077joanagmaia merged 4 commits intomainfrom
Conversation
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
2 similar comments
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
There was a problem hiding this comment.
Pull request overview
Fixes a backend 500 when updating contributor/member identities by preventing non-updatable fields from reaching the SQL UPDATE builder, adding backend allowlisting as defense-in-depth.
Changes:
- Backend:
updateMemberIdentitynow filters incoming update fields against an allowlist and dropsundefinedvalues before generating theSETclause. - Frontend: introduces
UpdateContributorIdentityPayloadand updates identity edit flow/API typings to send only intended updatable fields. - Frontend: identity edit form now explicitly constructs the PATCH payload instead of spreading the full identity object.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| services/libs/data-access-layer/src/members/identities.ts | Filters update payload keys to prevent invalid SQL updates from unexpected fields. |
| frontend/src/modules/contributor/types/Contributor.ts | Adds a dedicated update payload type with only updatable identity fields. |
| frontend/src/modules/contributor/store/contributor.actions.ts | Tightens typing for the identity update action to the new payload type. |
| frontend/src/modules/contributor/services/contributor.identities.api.service.ts | Updates PATCH method signature/body to use the new payload type. |
| frontend/src/modules/contributor/components/edit/identity/contributor-identity-edit.vue | Sends a curated subset of fields instead of spreading the full form object. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
4d7b352 to
a2e1939
Compare
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
a2e1939 to
f8890c8
Compare
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
| static async update(memberId: string, id: string, payload: UpdateContributorIdentityPayload) { | ||
| return authAxios.patch( | ||
| `/member/${memberId}/identity/${id}`, | ||
| payload, | ||
| { | ||
| ...identity, | ||
| segments: getSegments(), | ||
| params: { | ||
| segments: getSegments(), | ||
| }, | ||
| }, |
| const filtered = Object.fromEntries( | ||
| Object.entries(data).filter( | ||
| ([k, v]) => (UPDATABLE_IDENTITY_FIELDS as readonly string[]).includes(k) && v !== undefined, | ||
| ), |
|
Your PR title doesn't contain a Jira issue key. Consider adding it for better traceability. Example:
Projects:
Please add a Jira issue key to your PR title. |
Issue
Updating a contributor identity from the UI returned a 500 from the backend.
The frontend was spreading the full identity object into the PATCH payload, so fields that aren't updatable (e.g.
createdAt,memberId,id) were sent to the API. The backend'supdateMemberIdentitythen built a SQLUPDATEfrom every key it received, which produced an invalid statement and crashed the request.Fix
Frontend — only send fields the API is meant to accept.
UpdateContributorIdentityPayloadtype with the updatable fields only (value,type,platform,verified,source,sourceId,integrationId).contributor-identity-edit.vuenow picksvalueandtypeexplicitly instead of spreadingform.ContributorIdentitiesApiService.updateand theupdateContributorIdentitystore action are typed against the new payload.Backend — defense-in-depth so an unexpected field can't break the query again.
updateMemberIdentity(services/libs/data-access-layer/src/members/identities.ts) now filters the incomingdataagainst an allowlist (UPDATABLE_IDENTITY_FIELDS:platform,value,type,verified,verifiedBy,source,sourceId,integrationId) and dropsundefinedvalues before building theSETclause.Note
Medium Risk
Touches contributor identity update flow end-to-end (UI payload, API client, and SQL update builder); mistakes could prevent legitimate identity updates or silently drop fields.
Overview
Prevents contributor identity updates from triggering backend 500s by sending only allowed fields from the UI and tightening types via a new
UpdateContributorIdentityPayloadused by the store action andContributorIdentitiesApiService.update.Adds defense-in-depth in
updateMemberIdentityby allowlisting updatable columns and droppingundefinedvalues before building the SQLSETclause, avoiding invalid updates when unexpected fields are provided.Reviewed by Cursor Bugbot for commit 0df4b73. Bugbot is set up for automated code reviews on this repo. Configure here.